#include "aerosolwidget.h"

AerosolWidget::AerosolWidget(QWidget *parent):
 duration(100)
{
    Widget * w = qobject_cast<Widget*>(parent);
    if (w){
        this->parent = w->getCentreWidget();
    }else{
        this->parent = parent;
    }
    radius = 50;
    buttonSize = 24;
    style = "QPushButton{border-radius:12px;background-color:#363840;color:white;}QPushButton:press{background-color:#000409;border-width:3px;border-color:rgb(237,237,237)}QPushButton:hover{background-color:#000409}";
    direction = RIGHT;
    currentPos = QPoint(0, 100);
    mainButton = new MoveButton(this->parent);
    mainButton->setText("×");
    mainButton->resize(24,24);
    mainButton->move(currentPos);
    connect(mainButton,SIGNAL(clicked(bool)),this,SLOT(showState()));
    connect(mainButton,SIGNAL(moved()),this,SLOT(centreButtonMoved()));
    connect(mainButton,SIGNAL(docked(int)),this,SLOT(centreButtonDocked(int)));
    IsStretch = false;
    opacity = 0.6;
}

/**
 * @brief getSubButtons     获取所有子button
 * @return
 */
QList<QPushButton *> AerosolWidget::getSubButtons() const
{
    return subButtons;
}

/**
 * @brief setSubButtons         设置子button
 * @param value
 */
void AerosolWidget::setSubButtons(const QList<QPushButton *> &value)
{
    for (QPushButton* btn : subButtons){
        disconnect(btn,SIGNAL(clicked(bool)),this,SLOT(showState()));
    }
    subButtons = value;
    for (QPushButton* btn : value){
        btn->resize(buttonSize,buttonSize);
        btn->setParent(parent);
        btn->setVisible(true);
        connect(btn,SIGNAL(clicked(bool)),this,SLOT(showState()));
    }
    calsPosition();
    setButtonStyle();
}

/**
 * @brief getRadius     获取半径
 * @return
 */
int AerosolWidget::getRadius() const
{
    return radius;
}

/**
 * @brief setRadius     设置半径
 * @param value
 */
void AerosolWidget::setRadius(int value)
{
    radius = value;
}

/**
 * @brief getButtonSize     获取button尺寸
 * @return
 */
int AerosolWidget::getButtonSize() const
{
    return buttonSize;
}

/**
 * @brief setButtonSize     设置button尺寸
 * @param value
 */
void AerosolWidget::setButtonSize(int value)
{
    buttonSize = value;
}

/**
 * @brief getParent         获取父窗口
 * @return
 */
QWidget *AerosolWidget::getParent() const
{
    return parent;
}

/**
 * @brief setButtonStyle        设置button样式表
 * @param style
 */
void AerosolWidget::setButtonStyle(const QString &style)
{
    for (QPushButton* btn: subButtons){
        btn->setStyleSheet(style);
        btn->setWindowOpacity(opacity);
    }
    mainButton->setStyleSheet(style);
    mainButton->setWindowOpacity(opacity);
    this->style = style;
}

/**
 * @brief isStretch    伸展状态
 * @return
 */
bool AerosolWidget::isStretch() const
{
    return IsStretch;
}

/**
 * @brief setMainButtonText     设置主button text
 * @param text
 */
void AerosolWidget::setMainButtonText(const QString &text)
{
    mainButton->setText(text);
}

/**
 * @brief setMainButton     设置主button
 * @param button
 */
void AerosolWidget::setMainButton(MoveButton *button)
{
    if (mainButton){
        disconnect(mainButton,SIGNAL(clicked(bool)),this,SLOT(showState()));
        disconnect(mainButton,SIGNAL(realsed()),this,SLOT(clickSlot()));
        disconnect(mainButton,SIGNAL(moved()),this,SLOT(centreButtonMoved()));
    }
    mainButton = button;
    connect(mainButton,SIGNAL(clicked(bool)),this,SLOT(showState()));
    connect(mainButton,SIGNAL(moved()),this,SLOT(centreButtonMoved()));
    connect(mainButton,SIGNAL(docked(int)),this,SLOT(centreButtonDocked(int)));
}

/**
 * @brief getDirection      获取方向
 * @return
 */
AerosolWidget::DIRECTION AerosolWidget::getDirection() const
{
    return direction;
}

/**
 * @brief setDirection      设置方向
 * @param value
 */
void AerosolWidget::setDirection(const DIRECTION &value)
{
    switch (value) {
    case UP:
        currentPos.setY(0);
        break;
    case DOWN:
        currentPos.setY(parent->height()-mainButton->height());
        break;
    case LEFT:
        currentPos.setX(0);
        break;
    case RIGHT:
        currentPos.setX(parent->width()-mainButton->width());
        break;
    default:
        break;
    }
    mainButton->move(currentPos);
    direction = value;
    calsPosition();
}

void AerosolWidget::setButtonStyle()
{
    setButtonStyle(style);
}

void AerosolWidget::calsPosition()
{
    int count = subButtons.count();
    //计算按钮间角度
    if (count == 1){
        count = 2;
    }
    float step = 180/(count-1.0f);
    buttonPosAngle.clear();
    float startAngle = 0;
    switch(direction)
    {
    case UP:
        startAngle = 90;
        break;
    case DOWN:
        startAngle = -90;
        break;
    case LEFT:
        startAngle = 180;
        break;
    case RIGHT:
        startAngle = 0;
        break;
    default:
        break;
    }
    for (int i=0; i<count; ++i){
        buttonPosAngle.append(i*step+startAngle);
    }
    buttonPoints.clear();
    QPoint centrePos;
    centrePos=mainButton->pos();
    for (int i=0; i<count; ++i){
        float angle = buttonPosAngle.at(i);
        int x = sin(angle/180*3.1416)*radius+0.5;
        int y = cos(angle/180*3.1416)*radius+0.5;
        buttonPoints.append(centrePos+QPoint(x,y));
    }
}

void AerosolWidget::loops(QPropertyAnimation *animation)
{
    QEventLoop loop;
    connect(animation, SIGNAL(finished()),&loop,SLOT(quit()));
    animation->start();
    loop.exec();
}

void AerosolWidget::showState()
{
    switch(direction){
    case UP:
        mainButton->move(mainButton->x(),parent->height()-mainButton->height());
        break;
    case DOWN:
        mainButton->move(mainButton->x(),0);
        break;
    case LEFT:
        mainButton->move(parent->width()-mainButton->width(), mainButton->y());
        break;
    case RIGHT:
        mainButton->move(0, mainButton->y());
        break;
    default:
        break;
    }
    calsPosition();
    if (IsStretch){
        contractAnimation();
    }else{
        stretchAnimation();
    }
}

void AerosolWidget::centreButtonMoved()
{
    calsPosition();
    if (IsStretch){
        showCenter();
    }
}

void AerosolWidget::centreButtonDocked(int direction)
{
    switch (direction) {
    case 1:
        this->direction = DOWN;
        break;
    case 2:
        this->direction = UP;
        break;
    case 3:
        this->direction = RIGHT;
        break;
    case 4:
        this->direction = LEFT;
        break;
    default:
        break;
    }
    calsPosition();
}

/**
 * @brief stretchAnimation      伸展动画
 */
void AerosolWidget::stretchAnimation()
{
    if (isStretch()){
        return;
    }
    QList<QPropertyAnimation*> animationList;
    for (int i=0; i<subButtons.count(); ++i){
        QPropertyAnimation * action = new QPropertyAnimation(subButtons.at(i),"pos");
        action->setDuration(duration);
        action->setStartValue(mainButton->pos());
        action->setEndValue(buttonPoints.at(i));
        action->setEasingCurve(curve);
        animationList.append(action);
        subButtons.at(i)->show();
    }
    for (int i=0; i<subButtons.count()-1; ++i){
        animationList.at(i)->start();
    }
    loops(animationList.at(subButtons.count()-1));
    for (int i=0; i<animationList.count(); ++i){
        delete animationList.at(i);
    }
    showStretch();
}

/**
 * @brief contractAnimation     收缩动画
 */
void AerosolWidget::contractAnimation()
{
    if (!isStretch()){
        return;
    }
    QList<QPropertyAnimation*> animationList;
    for (int i=0; i<subButtons.count(); ++i){
        QPropertyAnimation * action = new QPropertyAnimation(subButtons.at(i),"pos");
        action->setDuration(duration);
        action->setEndValue(mainButton->pos());
        action->setStartValue(buttonPoints.at(i));
        action->setEasingCurve(curve);
        animationList.append(action);
    }
    for (int i=0; i<subButtons.count()-1; ++i){
        animationList.at(i)->start();
    }
    loops(animationList.at(subButtons.count()-1));
    for (int i=0; i<animationList.count(); ++i){
        delete animationList.at(i);
    }
    showCenter();
}

/**
 * @brief showCenter        显示收缩
 */
void AerosolWidget::showCenter()
{
    for (int i=0; i<subButtons.count(); ++i){
        subButtons.at(i)->move(mainButton->pos());
        subButtons.at(i)->hide();
    }
    mainButton->setText("＋");
    IsStretch = false;
}

/**
 * @brief showStretch       显示伸展
 */
void AerosolWidget::showStretch()
{
    for (int i=0; i<subButtons.count(); ++i){
        subButtons.at(i)->move(buttonPoints.at(i));
        subButtons.at(i)->show();
    }
    mainButton->setText("×");
    IsStretch = true;
}

/**
 * @brief setPos        设置位置
 * @param value
 */
void AerosolWidget::setPos(const int &value)
{
    switch(direction){
    case UP:
    case DOWN:
        currentPos.setX(value);
        break;
    case LEFT:
    case RIGHT:
        currentPos.setY(value);
        break;
    default:
        break;
    }
    mainButton->move(currentPos);
    calsPosition();
}

/**
 * @brief setMoveEnable     设置窗口可移动
 * @param enable
 */
void AerosolWidget::setMoveEnable(bool enable)
{
    mainButton->setMoveEnable(enable);
}

bool AerosolWidget::moveEnabled()
{
    return mainButton->moveEnabled();
}

void AerosolWidget::setOpacity(float value)
{
    opacity = value;
}

int AerosolWidget::getDuration() const
{
    return duration;
}

void AerosolWidget::setDuration(int value)
{
    duration = value;
}

QEasingCurve AerosolWidget::getCurve() const
{
    return curve;
}

void AerosolWidget::setCurve(const QEasingCurve &value)
{
    curve = value;
}
